using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace UnityEngine.UI
{ 

    public class SlicedImage : Image
    {
        static readonly Vector2[] s_VertScratch = new Vector2[4];
        static readonly Vector2[] s_UVScratch2 = new Vector2[16];
        public float radius;
        public bool useSlice = true;
        protected override void OnPopulateMesh(VertexHelper toFill)
        { 
            if(useSlice)
            { 
                GenerateSlicedSprite(toFill);
            }
            else
            {
                base.OnPopulateMesh(toFill);
            }

            //switch (type)
            //{
            //    case Type.Sliced:
            //        GenerateSlicedSprite(toFill);
            //        break;
            //    //default:
            //    //    base.OnPopulateMesh(toFill);
            //    //    break;
            //}
        }


        private Vector4 GetAdjustedBorders(Vector4 border, Rect adjustedRect)
        {
            Rect originalRect = rectTransform.rect;

            for (int axis = 0; axis <= 1; axis++)
            {
                float borderScaleRatio;

                // The adjusted rect (adjusted for pixel correctness)
                // may be slightly larger than the original rect.
                // Adjust the border to match the adjustedRect to avoid
                // small gaps between borders (case 833201).
                if (originalRect.size[axis] != 0)
                {
                    borderScaleRatio = adjustedRect.size[axis] / originalRect.size[axis];
                    border[axis] *= borderScaleRatio;
                    border[axis + 2] *= borderScaleRatio;
                }

                // If the rect is smaller than the combined borders, then there's not room for the borders at their normal size.
                // In order to avoid artefacts with overlapping borders, we scale the borders down to fit.
                float combinedBorders = border[axis] + border[axis + 2];
                if (adjustedRect.size[axis] < combinedBorders && combinedBorders != 0)
                {
                    borderScaleRatio = adjustedRect.size[axis] / combinedBorders;
                    border[axis] *= borderScaleRatio;
                    border[axis + 2] *= borderScaleRatio;
                }
            }
            return border;
        }

        /// <summary>
        /// Generate vertices for a 9-sliced Image.
        /// </summary>
        private void GenerateSlicedSprite(VertexHelper toFill)
        {
            //if (!hasBorder)
            //{
            //    GenerateSimpleSprite(toFill, false);
            //    return;
            //}

            var activeSprite = this.sprite;

            Vector4 outer, inner, padding, border;

            if (activeSprite != null)
            {
                outer = Sprites.DataUtility.GetOuterUV(activeSprite);
                inner = Sprites.DataUtility.GetInnerUV(activeSprite);
                padding = Sprites.DataUtility.GetPadding(activeSprite);
                //border = activeSprite.border;


                inner.x = inner.z = outer.x;
                inner.y = inner.w = 0.5f;

                outer.x = outer.z;
                outer.y = outer.w = 0.5f;



                if(radius <= 0)
                {
                    radius = sprite.rect.width;
                }


                border = Vector4.one * radius;

                padding = padding.z * Vector4.one;
            }
            else
            {
                outer = Vector4.zero;
                inner = Vector4.zero;
                padding = Vector4.zero;
                border = Vector4.zero;
            }

            Rect rect = GetPixelAdjustedRect();

            Vector4 adjustedBorders = GetAdjustedBorders(border / multipliedPixelsPerUnit, rect);
            padding = padding / multipliedPixelsPerUnit;

            s_VertScratch[0] = new Vector2(padding.x, padding.y);
            s_VertScratch[3] = new Vector2(rect.width - padding.z, rect.height - padding.w);

            s_VertScratch[1].x = adjustedBorders.x;
            s_VertScratch[1].y = adjustedBorders.y;

            s_VertScratch[2].x = rect.width - adjustedBorders.z;
            s_VertScratch[2].y = rect.height - adjustedBorders.w;

            for (int i = 0; i < 4; ++i)
            {
                s_VertScratch[i].x += rect.x;
                s_VertScratch[i].y += rect.y;
            }


            for(var i = 0;i < s_UVScratch2.Length; i++)
            {
                var xLimit = i % 4 == 0 || i % 4 == 3;
                var yLimit = i / 4 == 0 || i / 4 == 3;


                s_UVScratch2[i] = new Vector2(xLimit? 1: 0, yLimit ? 1 : 0);
            }

            toFill.Clear();

            for (int x = 0; x < 3; ++x)
            {
                int x2 = x + 1;

                for (int y = 0; y < 3; ++y)
                {
                    if (!fillCenter && x == 1 && y == 1)
                        continue;

                    int y2 = y + 1;


                    AddQuad(toFill,
                        new Vector2(s_VertScratch[x].x, s_VertScratch[y].y),
                        new Vector2(s_VertScratch[x2].x, s_VertScratch[y2].y),
                        color,
                        x,
                        y);
                }
            }
        }


        static void AddQuad(VertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector3[] quadUVs)
        {
            int startIndex = vertexHelper.currentVertCount;

            for (int i = 0; i < 4; ++i)
                vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]);

            vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
            vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);
        }

        static void AddQuad(VertexHelper vertexHelper, Vector2 posMin, Vector2 posMax, Color32 color, int x, int y)
        {
            int startIndex = vertexHelper.currentVertCount;

            vertexHelper.AddVert(new Vector3(posMin.x, posMin.y, 0), color, s_UVScratch2[y * 4 + x]);
            vertexHelper.AddVert(new Vector3(posMin.x, posMax.y, 0), color, s_UVScratch2[(y + 1) * 4 + x]);
            vertexHelper.AddVert(new Vector3(posMax.x, posMax.y, 0), color, s_UVScratch2[(y + 1) * 4 + x + 1]);
            vertexHelper.AddVert(new Vector3(posMax.x, posMin.y, 0), color, s_UVScratch2[(y) * 4 + x + 1]);

            vertexHelper.AddTriangle(startIndex, startIndex + 1, startIndex + 2);
            vertexHelper.AddTriangle(startIndex + 2, startIndex + 3, startIndex);
        }
    }
}